<template>
  <div class="voice-button-container">
    <!-- 录音按钮 -->
    <a-button
      :type="isRecording ? 'danger' : 'default'"
      :loading="isProcessing"
      :disabled="!isSupported || disabled"
      size="large"
      shape="circle"
      class="voice-button"
      :class="{ 'recording': isRecording, 'processing': isProcessing }"
      @click="toggleRecording"
      :title="buttonTitle"
    >
      <template #icon>
        <AudioOutlined v-if="!isRecording" />
        <StopOutlined v-else />
      </template>
    </a-button>

    <!-- 录音状态提示 -->
    <div class="status-indicator" v-if="isRecording || isProcessing">
      <div class="status-text">
        <span v-if="isProcessing" class="processing">处理中...</span>
        <span v-else-if="isRecording" class="recording">
          录音中 {{ recordingDuration.toFixed(1) }}s
        </span>
      </div>
      
      <!-- 录音波形动画 -->
      <div class="wave-animation" v-if="isRecording">
        <div class="wave-bar" v-for="i in 5" :key="i" :style="{ animationDelay: `${i * 0.1}s` }"></div>
      </div>
    </div>

    <!-- 错误信息显示 -->
    <div v-if="errorMessage" class="error-message">
      {{ errorMessage }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { message } from 'ant-design-vue'
import { AudioOutlined, StopOutlined } from '@ant-design/icons-vue'
import { useAuthStore } from '@/stores'
import { Codewin } from '@/api/generated/Codewin'

interface Props {
  maxDuration?: number // 最大录音时长（秒）
  language?: string // 语音识别语言
  disabled?: boolean // 是否禁用
}

interface Emits {
  transcriptionUpdate: [text: string, audioUrl: string]
  recordingStart: []
  recordingStop: []
  error: [error: string]
}

const props = withDefaults(defineProps<Props>(), {
  maxDuration: 60,
  language: 'zh',
  disabled: false
})

const emit = defineEmits<Emits>()

// 组件状态
const isRecording = ref(false)
const isProcessing = ref(false)
const recordingDuration = ref(0)
const errorMessage = ref('')

// 媒体相关
let mediaRecorder: MediaRecorder | null = null
let audioStream: MediaStream | null = null
let recordingTimer: number | null = null
let audioChunks: Blob[] = []

// 检查浏览器支持
const isSupported = computed(() => {
  if (!(
    navigator.mediaDevices && 
    typeof navigator.mediaDevices.getUserMedia === 'function' &&
    typeof MediaRecorder === 'function'
  )) {
    return false
  }
  
  return MediaRecorder.isTypeSupported('audio/mp3') ||
         MediaRecorder.isTypeSupported('audio/mpeg') ||
         MediaRecorder.isTypeSupported('audio/webm;codecs=opus')
})

// 按钮标题
const buttonTitle = computed(() => {
  if (!isSupported.value) return '您的浏览器不支持录音功能'
  if (props.disabled) return '录音功能已禁用'
  if (isProcessing.value) return '正在处理录音...'
  if (isRecording.value) return '点击停止录音'
  return '点击开始录音'
})

// 获取认证store和API实例
const authStore = useAuthStore()
const api = new Codewin({
  baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
  securityWorker: () => ({
    headers: {
      Authorization: `Bearer ${authStore.token}`
    }
  })
})

// 初始化录音
const initializeRecording = async () => {
  try {
    if (!isSupported.value) {
      throw new Error('您的浏览器不支持录音功能')
    }

    // 获取音频流
    audioStream = await navigator.mediaDevices.getUserMedia({
      audio: {
        echoCancellation: true,
        noiseSuppression: true,
        sampleRate: 16000
      }
    })

    // 创建MediaRecorder - 优先使用MP3格式
    let mimeType = 'audio/webm;codecs=opus' // 默认格式
    
    if (MediaRecorder.isTypeSupported('audio/mp3')) {
      mimeType = 'audio/mp3'
    } else if (MediaRecorder.isTypeSupported('audio/mpeg')) {
      mimeType = 'audio/mpeg'
    }
    
    mediaRecorder = new MediaRecorder(audioStream, {
      mimeType: mimeType
    })

    // 监听录音数据
    mediaRecorder.ondataavailable = (event) => {
      if (event.data.size > 0) {
        audioChunks.push(event.data)
      }
    }

    mediaRecorder.onstart = () => {
      emit('recordingStart')
      startRecordingTimer()
    }

    mediaRecorder.onstop = () => {
      emit('recordingStop')
      stopRecordingTimer()
    }

    return true
  } catch (error) {
    let errorMsg = '录音初始化失败'
    
    if (error instanceof Error) {
      if (error.name === 'NotAllowedError' || error.message.includes('Permission denied')) {
        errorMsg = '麦克风权限被拒绝，请在浏览器设置中允许访问麦克风'
      } else if (error.name === 'NotFoundError') {
        errorMsg = '未找到可用的麦克风设备'
      } else if (error.name === 'NotSupportedError') {
        errorMsg = '您的浏览器不支持录音功能'
      } else {
        errorMsg = error.message
      }
    }
    
    handleError(errorMsg)
    return false
  }
}

// 处理录音完成后的上传和转录
const processRecording = async () => {
  try {
    isProcessing.value = true
    
    // 创建音频文件 - 根据录音格式确定文件类型
    let mimeType = 'audio/webm;codecs=opus'
    let fileExtension = 'webm'
    
    if (mediaRecorder && mediaRecorder.mimeType) {
      mimeType = mediaRecorder.mimeType
      if (mimeType.includes('mp3')) {
        fileExtension = 'mp3'
      } else if (mimeType.includes('mpeg')) {
        fileExtension = 'mp3'
      }
    }
    
    const audioBlob = new Blob(audioChunks, { type: mimeType })
    const audioFile = new File([audioBlob], `recording_${Date.now()}.${fileExtension}`, {
      type: mimeType
    })
    
    console.log('准备上传文件:', {
      name: audioFile.name,
      size: audioFile.size,
      type: audioFile.type,
      extension: fileExtension,
      actualMimeType: mimeType
    })
    
    // 上传文件
    const uploadResult = await api.uploadFile({ file: audioFile })
    console.log('上传结果:', uploadResult)
    
    if (!uploadResult.data || uploadResult.data.code != 0) {
      throw new Error(`文件上传失败: ${uploadResult.data?.message || uploadResult.data?.data || '未知错误'}`)
    }
    
    const fileUrl = uploadResult.data.data
    if (!fileUrl) {
      throw new Error('未获取到文件URL')
    }
    
    // 调用语音转文本接口
    console.log('调用语音转文本接口，参数:', {
      url: fileUrl,
      language: props.language
    })
    
    const transcribeResult = await api.transcribe({
      url: fileUrl,
      language: props.language
    })
    
    console.log('语音转文本结果:', transcribeResult)
    
    if (!transcribeResult.data || transcribeResult.data.code != 0) {
      throw new Error(`语音转文本失败: ${transcribeResult.data?.message || transcribeResult.data?.data || '未知错误'}`)
    }
    
    const transcribedText = transcribeResult.data.data
    if (transcribedText) {
      emit('transcriptionUpdate', transcribedText, fileUrl)
      message.success('语音识别完成')
    }
    
  } catch (error) {
    const errorMsg = error instanceof Error ? error.message : '处理录音失败'
    handleError(errorMsg)
  } finally {
    isProcessing.value = false
  }
}

// 切换录音状态
const toggleRecording = () => {
  if (props.disabled || isProcessing.value || !isSupported.value) return
  
  if (isRecording.value) {
    stopRecording()
  } else {
    startRecording()
  }
}

// 开始录音
const startRecording = async () => {
  try {
    // 初始化录音设备
    const recordingReady = await initializeRecording()
    if (!recordingReady) return

    // 开始录音
    if (mediaRecorder && mediaRecorder.state === 'inactive') {
      audioChunks = [] // 清空之前的录音数据
      mediaRecorder.start(1000) // 每秒收集一次数据
      isRecording.value = true
      errorMessage.value = ''
    }
  } catch (error) {
    handleError('开始录音失败')
  }
}

// 停止录音
const stopRecording = async () => {
  if (mediaRecorder && mediaRecorder.state === 'recording') {
    mediaRecorder.stop()
  }
  
  if (audioStream) {
    audioStream.getTracks().forEach(track => track.stop())
    audioStream = null
  }
  
  isRecording.value = false
  
  // 处理录音完成后的上传和转录
  if (audioChunks.length > 0) {
    await processRecording()
  }
}

// 开始录音计时
const startRecordingTimer = () => {
  recordingDuration.value = 0
  recordingTimer = window.setInterval(() => {
    recordingDuration.value += 0.1
    
    // 检查是否超过最大录音时长
    if (recordingDuration.value >= props.maxDuration) {
      stopRecording()
      message.warning(`录音已达到最大时长 ${props.maxDuration} 秒`)
    }
  }, 100)
}

// 停止录音计时
const stopRecordingTimer = () => {
  if (recordingTimer) {
    clearInterval(recordingTimer)
    recordingTimer = null
  }
}

// 处理错误
const handleError = (error: string) => {
  errorMessage.value = error
  isRecording.value = false
  isProcessing.value = false
  stopRecordingTimer()
  emit('error', error)
  message.error(error)
}

// 组件挂载时的初始化
onMounted(() => {
  // 检查浏览器支持
  if (!isSupported.value) {
    errorMessage.value = '您的浏览器不支持录音功能'
  }
})

// 组件卸载时清理
onUnmounted(() => {
  stopRecordingTimer()
  if (audioStream) {
    audioStream.getTracks().forEach(track => track.stop())
  }
})

// 暴露方法给父组件
defineExpose({
  startRecording,
  stopRecording,
  toggleRecording,
  isRecording: computed(() => isRecording.value),
  isProcessing: computed(() => isProcessing.value)
})
</script>

<style scoped>
.voice-button-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.voice-button {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
  border: 2px solid #d9d9d9;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.voice-button:hover {
  transform: scale(1.05);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.voice-button.recording {
  background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%) !important;
  border-color: #ff4d4f !important;
  color: white !important;
  animation: pulse 1.5s infinite;
}

.voice-button.processing {
  background: linear-gradient(135deg, #faad14 0%, #ffc53d 100%) !important;
  border-color: #faad14 !important;
  color: white !important;
}

.voice-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

@keyframes pulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(255, 77, 79, 0.4);
  }
  50% {
    transform: scale(1.05);
    box-shadow: 0 0 0 10px rgba(255, 77, 79, 0);
  }
}

.status-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-height: 40px;
}

.status-text {
  font-size: 12px;
  font-weight: 500;
  text-align: center;
}

.status-text .recording {
  color: #ff4d4f;
  animation: blink 1.5s infinite;
}

.status-text .processing {
  color: #faad14;
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.wave-animation {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 20px;
}

.wave-bar {
  width: 3px;
  background: linear-gradient(to top, #ff4d4f, #ff7875);
  border-radius: 2px;
  animation: wave 1.2s ease-in-out infinite;
}

@keyframes wave {
  0%, 100% { height: 4px; }
  50% { height: 16px; }
}

.error-message {
  font-size: 12px;
  color: #ff4d4f;
  text-align: center;
  padding: 8px;
  background: #fff2f0;
  border: 1px solid #ffccc7;
  border-radius: 4px;
  margin-top: 8px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .voice-button {
    width: 44px;
    height: 44px;
  }
  
  .status-text {
    font-size: 11px;
  }
}
</style>